package sealte.util.date;

import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 日期常用功能类
 * @author SEALTE
 * 注：日期格式之间的转换大体分类
 * 1、Date型转换成String型
 * 2、String型之间相互转换
 * 3、String型转换成Date型-较复杂
 */
public class DateUtil {
	
	private static Map<String,String> monthMap = new HashMap<String,String>();
	
	static{
		monthMap.put("Jan", "01");
		monthMap.put("Feb", "02");
		monthMap.put("Mar", "03");
		monthMap.put("Apr", "04");
		monthMap.put("May", "05");
		monthMap.put("Jun", "06");
		monthMap.put("Jul", "07");
		monthMap.put("Aug", "08");
		monthMap.put("Sep", "09");
		monthMap.put("Oct", "10");
		monthMap.put("Nov", "11");
		monthMap.put("Dec", "12");
	}
	
	/**
	 * 得到日期时间的字符串格式
	 * @param date 需要格式化的日期
	 * @param haveS 是否带三位毫秒数
	 * @return 日期时间字符串yyyyMMddHHmmss[.SSS]
	 */
	public static String getDateString(Date date,boolean haveS){
		if(haveS){
			return new SimpleDateFormat("yyyyMMddHHmmss.SSS").format(date);
		}else{
			return new SimpleDateFormat("yyyyMMddHHmmss").format(date);
		}
	}
	
	/**
	 * 得到当前日期时间的字符串形式
	 * @param haveS 是否带三位毫秒数
	 * @return 日期时间字符串yyyyMMddHHmmss
	 */
	public static String getCurrentDateString(boolean haveS){
		Date date = new Date();
		return getDateString(date,haveS);
	}
	
	/**
	 * 将指定字符串解析成日期
	 * @param str 三种长度的日期字符串
	 * @return Date类型日期
	 */
	public static Date getDate(String str){
		if(null==str){
			return null;
		}else if(str.length()==8){ //str-yyyyMMdd
			return new SimpleDateFormat("yyyyMMdd").parse(str, new ParsePosition(0));
		}else if(str.length()==14){ //str-yyyyMMddHHmmss
			return new SimpleDateFormat("yyyyMMddHHmmss").parse(str, new ParsePosition(0));
		}else if(str.length()==18){ //str-yyyyMMddHHmmss.SSS
			return new SimpleDateFormat("yyyyMMddHHmmss.SSS").parse(str, new ParsePosition(0));
		}else{
			return null;
		}
	}
	
	/**
	 * 根据原始日期和变化参数计算出最终日期
	 * @param orgDate 原始日期
	 * @param year 变化年数
	 * @param month 变化月数
	 * @param day 变化天数
	 * @param hour 变化小时数
	 * @param minute 变化分钟数
	 * @param second 变化秒数
	 * @return 变化之后的日期
	 */
	public static Date getChange(Date orgDate, int year, int month, int day, 
			int hour, int minute, int second){
		Calendar c = Calendar.getInstance();
		c.setTime(orgDate);
		c.add(Calendar.YEAR, year);
		c.add(Calendar.MONTH, month);
		c.add(Calendar.DATE, day);
		c.add(Calendar.HOUR, hour);
		c.add(Calendar.MINUTE, minute);
		c.add(Calendar.SECOND, second);
		return c.getTime();
	}
	
	/**
	 * 得到调整格式之后的日期时间
	 * @param str yyyyMMddHHmmss[.SSS]格式的日期时间
	 * @param haveS 是否带三位毫秒数
	 * @return yyyy-MM-dd HH:mm:ss[.SSS]格式的日期时间
	 */
	public static String getDateTimeRF(String str,boolean haveS){
		if(null==str){
			return null;
		}else{
			String str2 = str.substring(0, 4)+"-"+str.substring(4, 6)+"-"+str.substring(6, 8)
					+" "+str.substring(8, 10)+":"+str.substring(10, 12);
			if(haveS){
				return str2 + ":" + str.substring(12);
			}else{
				return str2 + ":" + str.substring(12,14);
			}
		}
	}
	
	/**
	 * 得到调整格式之后的日期
	 * @param str yyyyMMdd[HHmmss[.SSS]]格式的日期
	 * @return yyyy-MM-dd格式的日期
	 */
	public static String getDateRF(String str){
		StringBuffer sb = new StringBuffer();
		if(null==str){
			//return ""
		}else{ 
			sb.append(str.substring(0, 4)).append("-").append(str.substring(4, 6)).append("-")
			  .append(str.substring(6, 8));
		}
		return sb.toString();
	}
	
	/**
	 * 得到调整格式之后的时间
	 * @param str [yyyyMMdd]HHmmss[.SSS]格式的时间
	 * @param haveS 是否带三位毫秒数
	 * @return HH:mm:ss[.SSS]格式的时间
	 */
	public static String getTimeRF(String str,boolean haveS){
		StringBuffer sb = new StringBuffer();
		if(null==str){
			//return ""
		}else if(str.length()<=10){ //str-HHmmss[.SSS]
			sb.append(str.substring(0, 2)).append(":").append(str.substring(2, 4)).append(":");
			if(haveS){
				sb.append(str.substring(4));
			}else{
				sb.append(str.substring(4,6));
			}
		}else{ //str-yyyyMMddHHmmss[.SSS]
			sb.append(str.substring(8, 10)).append(":").append(str.substring(10, 12)).append(":");
			if(haveS){
				sb.append(str.substring(12));
			}else{
				sb.append(str.substring(12,14));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 计算两个日期之间的天数
	 * @param sBeginDate 起始日期字符串
	 * @param sEndDate 结束日期字符串
	 * @param printDetail 是否打印计算过程
	 * @return 相差天数
	 */
	public static int getAllDays(String sBeginDate, String sEndDate, boolean printDetail) {
        int iDays = 0;
        Calendar c = Calendar.getInstance();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatter2 = new SimpleDateFormat("yyyyMMdd");
        String sTemp = "";
        Date dBeginDate;
        while (Integer.parseInt(sBeginDate) <= Integer.parseInt(sEndDate)) {
            sTemp = sBeginDate.substring(0, 4) + "-" +
                    sBeginDate.substring(4, 6) +
                    "-" + sBeginDate.substring(6, 8);
            dBeginDate = formatter.parse(sTemp, new ParsePosition(0));
            c.setTime(dBeginDate);
            c.add(Calendar.DATE, 1);
            dBeginDate = c.getTime();
            sBeginDate = formatter2.format(dBeginDate);
            iDays = iDays + 1;
            if(printDetail){
            	System.out.println(sBeginDate + "/" + sEndDate);
            }
        }
        return iDays;
    }
	
	/**
	 * 将标准时间格式的字符串转换成yyyyMMddHHmmss格式
	 * @param str 标准时间格式字符串
	 * @param isLocal 是否去掉CST时区转换时存在的误差
	 * @return 转换成yyyyMMddHHmmss格式之后的日期字符串
	 */
	public static String getDateString(String str, boolean isChina){
		@SuppressWarnings("deprecation")
		Date date = new Date(str);
		if(isChina){
			//美国和中国时区所写均为CST，new Date()时，默认采用美国时间
			date = getChange(date, 0, 0, 0, -14, 0, 0);
		}
		return new SimpleDateFormat("yyyyMMddHHmmss").format(date);
	}
	
	/**
	 * 将标准时间格式的字符串转换成yyyyMMddHHmmss格式
	 * @param str 标准时间格式字符串
	 * @return 转换成yyyyMMddHHmmss格式之后的日期字符串
	 */
	public static String getDateString(String str){
		return str.substring(24) + monthMap.get(str.substring(4, 7)) + str.substring(8, 10)
				+ str.substring(11, 13) + str.substring(14, 16) + str.substring(17, 19);
	}
	
	/**
	 * 获得给定年给定月的最后一天
	 * @param year 给定年
	 * @param month 给定月
	 * @return 给定年给定月的最后一天
	 */
	public static String getLastDayOfMonth(String yearStr,String monthStr){
		int year = Integer.valueOf(yearStr).intValue();
		int month = Integer.valueOf(monthStr).intValue();
		if(month == 12){
			++year;
			month = 0;
		}
		Calendar cl = Calendar.getInstance();
		cl.set(1, year);
		cl.set(2, month);
		cl.set(5, 1);
		cl.add(5, -1);
		return String.valueOf(cl.get(5));
	}
	
}
